/*
JETware Hands-free Extension provides additional features for Windows Mobile HFP support.
Copyright (C) 2004-2009 Jim Thatcher

This program is free software; you can redistribute it and/or modify it under the terms of the 
GNU General Public License as published by the Free Software Foundation; version 2 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program; 
if not, write to the Free Software Foundation, Inc., 
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

Source Control header

$Workfile: NotifyMgr.h $
$Revision: 3 $
$Date: 3/24/07 11:56p $
*/
#include "windows.h"
#include <snapi.h>
#include "regext.h"
#include "msgqueue.h"
#include "BTHFExt.h"

#ifdef __cplusplus
extern "C" {
#endif
BOOL IsNotifyAvailable();
#ifdef __cplusplus
}
#endif


////////////////////////////////////////////////////////////////////////////////
// Bluetooth
// Gets a value indicating status of Bluetooth system
#define SN_BLUETOOTH_ROOT HKEY_LOCAL_MACHINE
#define SN_BLUETOOTH_PATH TEXT("System\\State\\Hardware")
#define SN_BLUETOOTH_VALUE TEXT("Bluetooth")
#define SN_HANDSFREE_VALUE TEXT("Handsfree")
#define SN_BLUETOOTH_HFP_CONTROL_BITMASK	16
#define SN_BLUETOOTH_HFP_AUDIO_BITMASK		32
#define SN_BLUETOOTH_A2DP_BITMASK			4
#define SN_BLUETOOTH_ALL_BITMASK			SN_BLUETOOTH_HFP_CONTROL_BITMASK | SN_BLUETOOTH_HFP_AUDIO_BITMASK | SN_BLUETOOTH_A2DP_BITMASK
#define SN_PHONE_STATUS_ALL_BITMASK			SN_PHONEROAMING_BITMASK | SN_PHONECALLONHOLD_BITMASK | SN_PHONECONFERENCECALL_BITMASK |  \
							SN_PHONEINCOMINGCALL_BITMASK | SN_PHONECALLCALLING_BITMASK | SN_PHONENOSERVICE_BITMASK | SN_PHONECALLTALKING_BITMASK

#define JET_NOTIFY_QUEUE_NAME _T("JetNotifyQueue")

#define JET_REPORT_CLIP	0x01
#define JET_REPORT_ELIP	0x02

// NOTIFY_TYPE is used to identify which notification is in the queue
enum NOTIFY_TYPE
{
	PHONE_STATUS = 0,
	BT_STATUS,
	UNREAD_MAIL,
	SIGNAL_LEVEL,
	OPERATOR_NAME,
	CALL_COUNT,
#ifdef USE_NOTIFY_CID
	CALLER_NAME,
	CALLER_NUMBER,
	TALKING_NAME,
	TALKING_NUMBER,
#endif
#ifdef USE_NOTIFY_HF
	HANDS_FREE,
#endif
	MAX_NOTIFY_TYPE
};

class CNotifyMgr
{
public:
	CNotifyMgr(HANDLE * phMsgQueue);
	~CNotifyMgr();
	BOOL StartIndicators();
	void StopIndicators();
	BOOL StartMail(DWORD dwMsgStore);
	BOOL StopMail(DWORD dwMsgStore);
#ifdef USE_NOTIFY_CID
	BOOL StartCallerID(WORD wIDType);
	BOOL StopCallerID(WORD wIDType);
#endif
	BOOL ProcessMessages();

	BOOL HFPConnected() { return( (m_dwBTStatus & SN_BLUETOOTH_HFP_CONTROL_BITMASK) ? TRUE : FALSE ); };
	BOOL HFPAudio()		{ return( (m_dwBTStatus & SN_BLUETOOTH_HFP_AUDIO_BITMASK) ? TRUE : FALSE ); };
	BOOL A2DPConnected(){ return( (m_dwBTStatus & SN_BLUETOOTH_A2DP_BITMASK) ? TRUE : FALSE ); };

	BOOL HasService()	{ return( (m_dwPhoneStatus & SN_PHONENOSERVICE_BITMASK) ? FALSE : TRUE ); };
	BOOL InCall()		{ return( (m_dwPhoneStatus & SN_PHONECALLTALKING_BITMASK) ? TRUE : FALSE ); };
	BOOL Ringing()		{ return( (m_dwPhoneStatus & SN_PHONEINCOMINGCALL_BITMASK) ? TRUE : FALSE ); };
	BOOL Dialing()		{ return( (m_dwPhoneStatus & SN_PHONECALLCALLING_BITMASK) ? TRUE : FALSE ); };
	WORD CallSetup()	{ return (Ringing() | Dialing()) ? ((Ringing()) ? CALLSETUP_INCOMING : CALLSETUP_OUTRING) : CALLSETUP_NONE; };
	// WORD BatteryLevel() { return m_wBatteryLevel; };
	WORD SignalLevel()	{ return (WORD)((m_dwSignal < 90) ? ((g_dwBatteryLevel + 10) / 20) : 5); };
	BOOL Roaming()		{ return( (m_dwPhoneStatus & SN_PHONEROAMING_BITMASK) ? TRUE : FALSE ); };
	WORD CallCount()	{ return m_wCallCount; };
	BOOL OnHold()		{ return( (m_dwPhoneStatus & SN_PHONECALLONHOLD_BITMASK) ? TRUE : FALSE ); };
	BOOL InConference()	{ return( (m_dwPhoneStatus & SN_PHONECONFERENCECALL_BITMASK) ? TRUE : FALSE ); };
	BOOL GetOperator(TCHAR * szOperator, DWORD dwSize);
#ifdef USE_NOTIFY_CID
	BOOL GetCallerName(TCHAR * szName, DWORD dwSize);
	BOOL GetCallerNumber(TCHAR * szNumber, DWORD dwSize);
	BOOL ReportCLIP()	{ return( (m_wCallIDActive & JET_REPORT_CLIP) ? TRUE : FALSE ); };
	BOOL ReportELIP()	{ return( (m_wCallIDActive & JET_REPORT_ELIP) ? TRUE : FALSE ); };
#endif
	BOOL MailNotifyEnabled(DWORD dwMsgStore) { return m_bMailEnabled[(dwMsgStore) ? 1 : 0]; };

private:
	BOOL	m_bMailEnabled[2];
	DWORD	m_dwSignal;
	TCHAR * m_szOperator;
#ifdef USE_NOTIFY_CID
	WORD	m_wCallIDActive;
	// TODO: Do we need to store caller ID info, or just report it when it changes?
	TCHAR * m_szCallerName;
	TCHAR * m_szCallerNumber;
#endif
	WORD	m_wCallCount;
	DWORD	m_dwPhoneStatus;
	DWORD	m_dwBTStatus;
#ifdef USE_NOTIFY_HF
	BOOL	m_bHandsfree;
#endif
	HANDLE m_hMsgQueue;
	HREGNOTIFY m_NotifyHandles[MAX_NOTIFY_TYPE];
};

extern CNotifyMgr * g_pNotify;